package server

import (
	"encoding/json"
	"errors"
	"fmt"
    "math/rand"
    "time"
	"license/plugin"
	"log"
	"strconv"

	"github.com/gin-gonic/gin"
)
var hserver *gin.Engine
var Port string //http端口

type License struct {
    Id int `json:"id,omitempty"`//指定 id
	Custom string `json:"custom,omitempty"` //客户
    Product string `json:"product,omitempty"` //产品
    ExpirDate string `json:"expirDate,omitempty"` //过期时间(支持续签)
    Status string `json:"status,omitempty"` //当前状态(有效/无效)
    PubKey string `json:"pubkey,omitempty"` //公钥
    PrivateKey string `json:"privatekey,omitempty"` //私钥
    IdentificationCode string `json:"identificationcode,omitempty"` //企业识别码
    Ownership string `json:"ownership,omitempty"` //维护人员
    Ipaddress string `json:"ipaddress,omitempty"` //注册IP地址
    Remark string `json:"remark,omitempty"` //备注
    CreateTime string `json:"createTime,omitempty"` //创建时间
    UpdateTime string `json:"updateTime,omitempty"` //更新时间
}


/*
CREATE TABLE license (
    id INT AUTO_INCREMENT PRIMARY KEY,
    custom VARCHAR(255),
    product VARCHAR(255),
    expirDate VARCHAR(255),
    status VARCHAR(255),
    pubkey VARCHAR(2000) DEFAULT NULL,
    privatekey VARCHAR(10000) DEFAULT NULL,
    identificationcode VARCHAR(255) DEFAULT NULL,
    ownership VARCHAR(255),
    ipaddress VARCHAR(50) DEFAULT NULL,
    remark VARCHAR(255) DEFAULT NULL
);

*/


func LicenseAdd(ctx *gin.Context){
        Authorization := ctx.GetHeader("Authorization")
        Authcode := checkAuth(Authorization)
        code := checkError(Authcode)
        if !code{
            log.Println(code)
            message := fmt.Sprintf("Authorization check failed")
            ctx.JSON(200,gin.H{"message":message,"code":"403"})
            return
        }  
        var license License
        err := ctx.BindJSON(&license)
    		if err != nil {
                ctx.JSON(200, gin.H{"error": "无效的JSON数据","code":500})
                return
		}
        code = Insert(license,Authorization)
        if code == true{
            ctx.JSON(200, gin.H{"code":200,"message": "数据已添加"})   
        }else{
            ctx.JSON(200, gin.H{"code":200,"message": "数据添加失败"})   
        }
}
func LicenseDelete(ctx *gin.Context){
        Authorization := ctx.GetHeader("Authorization")
        Authcode := checkAuth(Authorization)
        code := checkError(Authcode)
        if !code{
            log.Println(code)
            message := fmt.Sprintf("Authorization check failed")
            ctx.JSON(200,gin.H{"code":403,"message":message})
            return
        }
        var license License
        err := ctx.BindJSON(&license)
    		if err != nil {
			ctx.JSON(200, gin.H{"error": "无效的JSON数据","code":500})
			return
		}
        log.Println("delete",Authorization,license)
        code = Delete(license)
        if code == true{
            ctx.JSON(200, gin.H{"code":200,"message": "数据已删除"})
            return   
        }else{
            ctx.JSON(200, gin.H{"code":200,"message": "数据删除失败"})   
            return
        }
}
func LicenseUpdate(ctx *gin.Context){
        Authorization := ctx.GetHeader("Authorization")
        Authcode := checkAuth(Authorization)
        code := checkError(Authcode)
        if !code{
            log.Println(code)
            message := fmt.Sprintf("Authorization check failed")
            ctx.JSON(200,gin.H{"message":message,"code":403})
        }else{
            var license License
            err := ctx.BindJSON(&license)
            if err != nil {
                ctx.JSON(200, gin.H{"code":500,"error": fmt.Sprintf("无效的JSON数据%s",err.Error())})
            }else{
                code = Update(license)
                if code == true{
                    ctx.JSON(200, gin.H{"code":200,"message": "数据已更新"})   
                }else{
                    ctx.JSON(200, gin.H{"code":500,"message": "数据更新失败"})   
                }
            }
        }
}
func LicenseList(ctx *gin.Context){
        Authorization := ctx.GetHeader("Authorization")
        Authcode := checkAuth(Authorization)
        code := checkError(Authcode)
        if !code{
            log.Println(code)
            message := fmt.Sprintf("Authorization check failed")
            ctx.JSON(200,gin.H{"message":message,"code":403})
            return
        }else{
            licenses := Query() 
            jsonData, err := json.Marshal(licenses)
            if err != nil{
                message := fmt.Sprintf("err: %s",&err)
                ctx.JSON(200,gin.H{"message":message,"code":500})
            }else{
                ctx.JSON(200,gin.H{"data":string(jsonData),"code":200})
            }
        }
}


func Queryexpir(ctx *gin.Context){
        Authorization := ctx.GetHeader("Authorization")
        Authcode := checkAuth(Authorization)
        code := checkError(Authcode)
        if !code{
            log.Println(code)
            message := fmt.Sprintf("Authorization check failed")
            ctx.JSON(200,gin.H{"message":message,"code":403})
            return
        }else{
            licenses := QueryExpir() //查询即将过期license 进行邮件通知
            jsonData, err := json.Marshal(licenses)
            if err != nil{
                message := fmt.Sprintf("err: %s",&err)
                ctx.JSON(200,gin.H{"message":message,"code":500})
            }else{
                ctx.JSON(200,gin.H{"data":string(jsonData),"code":200})
        }
        }
}

// var licenses []License
func checkError(code error)(bool){
    if code == nil{
        return true
    }else{
        return false
    }
}
func checkAuth(Authorization string)(error){
    if Authorization == ""{
        return errors.New("Authorization is None")
    }else{
        users := QueryuserInfo(Authorization) //查询用户token 以及用户名
        if len(users) == 0{
            return errors.New("Authorization check failed")
        }else{
            return nil
        }
    }
}

type CreUser struct{
    Username string `json:"username,omitempty"`
    Role string `json:"role,omitempty"`
}

//create user
func CreateUser(ctx *gin.Context){
        Authorization := ctx.GetHeader("Authorization")
        Authcode := checkAuth(Authorization)
        code := checkError(Authcode)
        if !code{
            log.Println(code)
            message := fmt.Sprintf("Authorization check failed")
            ctx.JSON(200,gin.H{"message":message,"code":403})
            return
        }
            var user CreUser
            err := ctx.BindJSON(&user)
                if err != nil {
                    ctx.JSON(200, gin.H{"code":500,"error": fmt.Sprintf("无效的JSON数据%s",err.Error())})
                    return
            }
            log.Println(Authorization,"create user",user)
            token := randomString(20)
            crecode := CreateUserMode(user,token)
            if crecode{
                ctx.JSON(200, gin.H{"code":200,"message": fmt.Sprintf("用户创建成功"),"token":token})
            }else{
                ctx.JSON(200, gin.H{"code":200,"error": fmt.Sprintf("用户创建失败")})
        }
}

func randomString(length int) string {
    rand.Seed(time.Now().UnixNano())
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	randomBytes := make([]byte, length)
	for i := range randomBytes {
		randomBytes[i] = charset[rand.Intn(len(charset))]
	}
	return string(randomBytes)
}

//get rsa download file
func GetRsa(ctx *gin.Context){
    var filename string
    Authorization := ctx.GetHeader("Authorization")
    id := ctx.Query("id")
    genname := ctx.Query("genname")
    Authcode := checkAuth(Authorization)
    code := checkError(Authcode)
    if !code{
        log.Println(code)
        message := fmt.Sprintf("Authorization check failed")
        ctx.JSON(200,gin.H{"message":message,"code":403})
        return
    }
    if id == ""{
        message := fmt.Sprintf("license id is null")
        ctx.JSON(200,gin.H{"message":message,"code":500})
        return
    }
    lid,err := strconv.Atoi(id)
    if err != nil{
        message := fmt.Sprintf("license id is string")
        ctx.JSON(200,gin.H{"message":message,"code":500})
        return
    }
    GetKey := QueryRSA(lid)
    if len(GetKey) == 1{
        ciphertext := GetKey[0].ciphertext
        privatekey := GetKey[0].privatekey
        if privatekey != "" && ciphertext != ""{
            if genname == "privatekey"{
                filename,err = plugin.Writefile(id,privatekey)
            }else if genname == "ciphertext"{
                filename,err = plugin.Writefile(id,ciphertext)
            }
            if err != nil{
                message := fmt.Sprintf("filename: %s,rsa write failed err %s",filename,err.Error())
                ctx.JSON(200,gin.H{"message":message,"code":500})
                return
            }
            ctx.Header("Content-Disposition", "attachment; filename=id.pem")
            ctx.Header("Content-Type", "application/octet-stream")
            ctx.File(filename)
        }else{
            message := fmt.Sprintf("license %s privatekey or ciphertext is null",id)
            ctx.JSON(200,gin.H{"message":message,"code":500})
        }
    }else{
        message := fmt.Sprintf("license %s key is not unique",id)
        ctx.JSON(200,gin.H{"message":message,"code":500})
    }

}


//golang build client
func Gobuild(ctx *gin.Context){

}

func GetInfo(ctx *gin.Context){
        Authorization := ctx.GetHeader("Authorization")
        Authcode := checkAuth(Authorization)
        code := checkError(Authcode)
        if !code{
            log.Println(code)
            message := fmt.Sprintf("Authorization check failed")
            ctx.JSON(200,gin.H{"message":message,"code":403})
            return
        }else{
            users := QueryuserInfo(Authorization) //查询用户token 以及用户名
            jsonData, err := json.Marshal(users)
            log.Println(users,string(jsonData),err)
            if err != nil{
                message := fmt.Sprintf("err: %s",&err)
                ctx.JSON(200,gin.H{"message":message,"code":500})
            }else{
                ctx.JSON(200,gin.H{"data":string(jsonData),"code":200})
            }   
        }
}